package loginuser

import (
	"encoding/json"
	"os"
	"strings"

	"gitee.com/tomatomeatman/golang-repository/bricks/model/dbinfo"
	"gitee.com/tomatomeatman/golang-repository/bricks/model/emity"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/app"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/data/base64util"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/data/md5util"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/ginutil"
)

/**
 * 用户表LoginUser表基本业务操作结构体
 */
type LoginUserService struct {
	app.ServiceBaseFunc
}

/**
 * 新增
 * @param ctx Http请求对象
 * @param dbEntity 实体数据结构
 * @param params 数据
 * @return *emity.MsgEmity 返回执行结果
 */
func (service LoginUserService) Add(ctx ginutil.Context, dbEntity dbinfo.Entity, params map[string]interface{}) *emity.MsgEmity {
	sNo, ok := params["sNo"]
	if !ok || (strings.TrimSpace(sNo.(string)) == "") {
		return emity.MsgEmity{}.Err(8401, "工号作为唯一标识不能为空!") //在同一根部门下,工号必须唯一
	}

	sName, ok := params["sName"]
	if !ok || (strings.TrimSpace(sName.(string)) == "") {
		return emity.MsgEmity{}.Err(8402, "用户名称不能为空!") //在同一根部门下,工号必须唯一
	}

	temp := strings.ToLower(strings.TrimSpace(sNo.(string)))
	if (temp == "admin") || (temp == "superadmin") {
		return emity.MsgEmity{}.Err(8403, "特殊标识,禁止使用!")
	}

	temp = strings.ToLower(strings.TrimSpace(sName.(string)))
	if (temp == "admin") || (temp == "superadmin") {
		return emity.MsgEmity{}.Err(8404, "特殊名称,禁止使用!")
	}

	sPass, ok := params["sPass"]
	if !ok || (strings.TrimSpace(sPass.(string)) == "") {
		return emity.MsgEmity{}.Err(8405, "密码不能为空!")
	}

	appMd5Key := app.AppUtil{}.ReadConfigKey("App", "Md5Key", "555").(string)
	params["sPass"] = md5util.Lower(sPass, appMd5Key)

	sOwner, ok := params["sOwner"]
	if !ok || (strings.TrimSpace(sOwner.(string)) == "") {
		params["sOwner"] = "BaseSystem.LoginUser"
	}

	return service.ServiceBaseFunc.Add(ctx, dbEntity, params)
}

/**
 * 修改
 * @param entity 对象类型
 * @param id 记录编号值
 * @param iVersion 记录版本号
 * @param data 待更新的字段和值
 * @return *emity.MsgEmity 返回执行结果
 */
func (service LoginUserService) Edit(ctx ginutil.Context, entity dbinfo.Entity, id interface{}, iVersion int, data map[string]interface{}) *emity.MsgEmity {
	sNo, ok := data["sNo"]
	if ok && (strings.TrimSpace(sNo.(string)) == "") {
		return emity.MsgEmity{}.Err(8401, "工号作为唯一标识不能为空!") //在同一根部门下,工号必须唯一
	}

	if ok {
		temp := strings.ToLower(strings.TrimSpace(sNo.(string)))
		if (temp == "admin") || (temp == "superadmin") {
			return emity.MsgEmity{}.Err(8402, "特殊标识,禁止修改!")
		}
	}

	sName, ok := data["sName"]
	if ok && (strings.TrimSpace(sName.(string)) == "") {
		return emity.MsgEmity{}.Err(8403, "用户名称不能为空!") //在同一根部门下,工号必须唯一
	}

	if ok {
		temp := strings.ToLower(strings.TrimSpace(sName.(string)))
		if (temp == "admin") || (temp == "superadmin") {
			return emity.MsgEmity{}.Err(8404, "特殊名称,禁止使用!")
		}
	}

	delete(data, "sPass") //不允许修改密码

	sOwner, ok := data["sOwner"]
	if ok && (strings.TrimSpace(sOwner.(string)) == "") {
		data["sOwner"] = "BaseSystem.LoginUser"
	}

	return service.ServiceBaseFunc.Edit(ctx, entity, id, iVersion, data)
}

/**
 * 删除
 * @param entity 对象类型
 * @param id 记录编号值
 * @param iVersion 记录版本号
 * @return MsgEmity
 */
func (service LoginUserService) Del(ctx ginutil.Context, entity dbinfo.Entity, id interface{}, iVersion int) *emity.MsgEmity {
	if strings.Contains(",00000000,00000001,", id.(string)) {
		return emity.MsgEmity{}.Err(8101, "特殊用户，禁止删除！")
	}

	return service.ServiceBaseFunc.Del(ctx, entity, id, iVersion)
}

/**
 * 修改密码
 * @param ctx
 * @param entity
 * @param sId
 * @param sOldPass
 * @param sNewPass
 * @return MsgEmity
 */
func (service LoginUserService) EditPass(ctx ginutil.Context, entity dbinfo.Entity, sId, sOldPass, sNewPass, sOwner string) *emity.MsgEmity {
	if sId == "" {
		return emity.MsgEmity{}.Err(8001, "用户编号不能为空！")
	}

	if sOldPass == "" {
		return emity.MsgEmity{}.Err(8002, "旧密码不能为空！")
	}

	if sNewPass == "" {
		return emity.MsgEmity{}.Err(8003, "新密码不能为空！")
	}

	me := app.CommonDao{}.HasById(entity, sId)
	if !me.Gsuccess {
		return emity.MsgEmity{}.Err(8004, "没有查找到用户！")
	}

	me = app.CommonDao{}.GetValueByFieldName(entity, sId, []string{"iState", "sPass", "iVersion"}, "", false)
	if !me.Gsuccess {
		return emity.MsgEmity{}.Err(8005, "没有查找到对应用户！")
	}

	m := me.Gdata.(map[string]interface{})
	if m["iState"].(int64) != 1 {
		return emity.MsgEmity{}.Err(8007, "用户被限制！")
	}

	appMd5Key := app.AppUtil{}.ReadConfigKey("App", "Md5Key", "555").(string)
	sOldPassMd5 := md5util.Lower(sOldPass, appMd5Key)

	if sOldPassMd5 != m["sPass"].(string) {
		return emity.MsgEmity{}.Err(8008, "提供的旧密码错误！")
	}

	sNewPassMd5 := md5util.Lower(sNewPass, appMd5Key)
	if sNewPassMd5 == sOldPassMd5 {
		return emity.MsgEmity{}.Success(8999, "密码无需修改！")
	}

	tableInfo := entity.TableInfo()

	return LoginUserDao{}.EditPass(tableInfo.GsDbName, sId, sNewPassMd5, sOldPassMd5, sId, sOwner, m["iVersion"].(int64))
}

func (service LoginUserService) MapToJson(m interface{}, v any) error {
	str, err := json.Marshal(m)
	if err != nil {
		return err
	}

	err = json.Unmarshal(str, v)
	if err != nil {
		return err
	}

	return nil
}

// 重置密码
func (service LoginUserService) ResetPass(currentUserId, sId, sPass, sOwner string) *emity.MsgEmity {
	if sId == "" {
		return emity.MsgEmity{}.Err(8001, "用户编号不能为空！")
	}

	if strings.TrimSpace(currentUserId) == "" {
		return emity.MsgEmity{}.Err(8002, "未能获取操作人员信息！")
	}

	if (("00000000" == currentUserId) || ("00000001" == currentUserId)) && (sId == currentUserId) { //超级管理员登录/管理员或当前用户
		return emity.MsgEmity{}.Err(8003, "仅允许管理员或当前用户重置密码")
	}

	if strings.TrimSpace(sOwner) == "" {
		return emity.MsgEmity{}.Err(8004, "用户归属不能为空！")
	}

	entity := &LoginUser{}

	me := app.CommonDao{}.HasById(entity, sId)
	if !me.Gsuccess {
		return emity.MsgEmity{}.Err(8005, "没有查找到用户！")
	}

	me = app.CommonDao{}.GetValueByFieldName(entity, sId, []string{"iState", "sPass", "iVersion"}, "", false)
	if !me.Gsuccess {
		return emity.MsgEmity{}.Err(8006, "没有查找到对应用户！")
	}

	m := me.Gdata.(map[string]interface{})
	if m["iState"].(int64) != 1 {
		return emity.MsgEmity{}.Err(8007, "用户被限制！")
	}

	appMd5Key := app.AppUtil{}.ReadConfigKey("App", "Md5Key", "555").(string)
	sPassMd5 := md5util.Lower(sPass, appMd5Key)

	if m["sPass"].(string) != sPassMd5 {
		return emity.MsgEmity{}.Err(8008, "提供的操作密码错误!")
	}

	sNewPass := md5util.Lower("123456", appMd5Key)
	if sNewPass == sPassMd5 {
		return emity.MsgEmity{}.Success(8999, "密码无需修改重置！")
	}

	tableInfo := entity.TableInfo()
	return LoginUserDao{}.ResetPass(tableInfo.GsDbName, sId, sNewPass, sId, sOwner, m["iVersion"].(int64))
}

// 根据用户编号设置用户类型
func (service LoginUserService) EditUserType(currentUserId, sId, sType, sOwner string) *emity.MsgEmity {
	if sId == "" {
		return emity.MsgEmity{}.Err(8001, "用户编号不能为空！")
	}

	if strings.TrimSpace(sType) == "" {
		return emity.MsgEmity{}.Err(8002, "用户类型不能为空！")
	}

	if strings.TrimSpace(sOwner) == "" {
		return emity.MsgEmity{}.Err(8003, "用户归属不能为空！")
	}

	tableInfo := dbinfo.TableInfo{}.GetByEntity(&LoginUser{})
	return LoginUserDao{}.EditUserType(tableInfo.GsDbName, sId, sType, sOwner)
}

// 设置用户头像
func (service LoginUserService) EditUserHead(currentUserId, sHead string) *emity.MsgEmity {
	if currentUserId == "" {
		return emity.MsgEmity{}.Err(8001, "用户编号不能为空！")
	}

	if strings.TrimSpace(sHead) == "" {
		return emity.MsgEmity{}.Err(8002, "图片信息为空！")
	}

	//把base64图片转换为文件
	savePath := "./data/img/head/" + currentUserId + "/head.png"
	me := base64util.Base64ToPng(sHead, savePath)
	if !me.Gsuccess {
		return me.IncCode(8100)
	}

	return emity.MsgEmity{}.Success(8999, "设置成功！")
}

// 取用户头像
func (service LoginUserService) LookHead(currentUserId string) *emity.MsgEmity {
	if currentUserId == "" {
		return emity.MsgEmity{}.Err(8001, "用户编号不能为空！")
	}

	//把base64图片转换为文件
	headPath := "./data/img/head/" + currentUserId + "/head.png"
	// 读取图片文件
	data, err := os.ReadFile(headPath)
	if err != nil {
		return emity.MsgEmity{}.Err(8002, "读取图片文件失败！")
	}

	return emity.MsgEmity{}.Success(data, "设置成功！")
}
